home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 2 / Atari Mega Archive CD - Volume 2.iso / linux / src / atalnx_3.lzh / atari-linux-0.01pl3 / atari / config.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-06-12  |  5.3 KB  |  209 lines

  1. /*
  2.  *  linux/atari/config.c
  3.  *
  4.  *  Copyright (C) 1994 Björn Brauel
  5.  *
  6.  *  5/2/94 Roman Hodek:
  7.  *    Added setting of time_adj to get a better clock.
  8.  *
  9.  *  5/14/94 Roman Hodek:
  10.  *    gettod() for TT 
  11.  *
  12.  *  5/15/94 Roman Hodek:
  13.  *    hard_reset_now() for Atari (and others?)
  14.  *
  15.  * This file is subject to the terms and conditions of the GNU General Public
  16.  * License.  See the file README.legal in the main directory of this archive
  17.  * for more details.
  18.  */
  19.  
  20. /*
  21.  * Miscellaneous atari stuff
  22.  */
  23.  
  24. #include <linux/config.h>
  25. #include <linux/types.h>
  26. #include <linux/interrupt.h>
  27. #include <linux/mktime.h>
  28. #include <linux/mm.h>
  29. #include <linux/bootinfo.h>
  30. #include <linux/mc146818rtc.h>
  31.  
  32. #include <linux/atarihw.h>
  33. #include <linux/atariints.h>
  34.  
  35. #include <asm/system.h>
  36.  
  37.  
  38. extern long    time_adj;        /* from kernel/sched.c */
  39.  
  40.  
  41. void atari_sched_init (isrfunc timer_routine)
  42. {
  43.     /* set Timer A data Register */
  44.     mfp.tim_dt_a=INT_TICKS;
  45.  
  46.     /* install interrupt service routine for MFP Timer A */
  47.     add_isr (IRQ_MFP_TIMA, timer_routine, 0, NULL); 
  48.     /* start timer A, div = 1:100 */
  49.     mfp.tim_ct_a = 0x06; 
  50.     /* enable timer A Interrupt */   
  51.     mfp.int_en_a |= 0x20;
  52.  
  53.     /* The excact frequency of our timer is 2.4576 MHz / 100 / 246 =
  54.      * 99.90243902 Hz. This gives a difference of 9.76954 us to real time
  55.      * per clock tick. time_adj is in us scaled by 2^24, thus it should
  56.      * be 9.76954 * 2^24 = 163905683
  57.      */
  58.     time_adj = 163905683;
  59. }
  60.  
  61.  
  62. unsigned long atari_gettimeoffset (void)
  63. {
  64.     unsigned long ticks, flags;
  65.  
  66.     save_flags(flags);
  67.     cli();
  68.  
  69.     ticks = (unsigned long)mfp.tim_dt_a;
  70.     restore_flags(flags);
  71.     
  72.     ticks = (INT_TICKS-1) - ticks;
  73.     ticks = ticks * 10000L / INT_TICKS;
  74.     
  75.     return ticks;
  76.  
  77. }
  78.  
  79.  
  80. #define    RTC_READ(reg)                            \
  81.     ({    unsigned char    __val;                    \
  82.         tt_rtc.regsel = (reg);                    \
  83.         __val = tt_rtc.data;                    \
  84.         __val;                                    \
  85.     })
  86.  
  87. #define    RTC_WRITE(reg,val)                        \
  88.     do {                                        \
  89.         tt_rtc.regsel = (reg);                    \
  90.         tt_rtc.data = (val);                    \
  91.     } while(0)
  92.     
  93.  
  94. void atari_gettod( struct mktime *time )
  95.  
  96. {
  97.         int                i;
  98.         unsigned char    ctrl;
  99.         
  100.         for (i = 0 ; i < 1000000 ; i++)    /* may take up to 1 second... */
  101.             if (RTC_READ(RTC_FREQ_SELECT) & RTC_UIP)
  102.                 break;
  103.         for (i = 0 ; i < 1000000 ; i++)    /* must try at least 2.228 ms*/
  104.             if (!(RTC_READ(RTC_FREQ_SELECT) & RTC_UIP))
  105.                 break;
  106.  
  107.         time->sec  = RTC_READ(RTC_SECONDS);
  108.         time->min  = RTC_READ(RTC_MINUTES);
  109.         time->hour = RTC_READ(RTC_HOURS);
  110.         time->day  = RTC_READ(RTC_DAY_OF_MONTH);
  111.         time->mon  = RTC_READ(RTC_MONTH);
  112.         time->year = RTC_READ(RTC_YEAR);
  113.  
  114.         /* Adjust values (let the setup valid for TOS) */
  115.         time->mon--;
  116.         time->year += 70;
  117.  
  118.         ctrl = RTC_READ(RTC_CONTROL); 
  119.  
  120.         if (!(ctrl & RTC_DM_BINARY)) {
  121.             BCD_TO_BIN(time->sec);
  122.             BCD_TO_BIN(time->min);
  123.             BCD_TO_BIN(time->hour);
  124.             BCD_TO_BIN(time->day);
  125.             BCD_TO_BIN(time->mon);
  126.             BCD_TO_BIN(time->year);
  127.         }
  128.         if (!(ctrl & RTC_24H)) {
  129.             if (time->hour & 0x80) {
  130.                 time->hour &= ~0x80;
  131.                 time->hour += 12;
  132.             }
  133.         }
  134. }
  135.  
  136.  
  137. void waitbut (void)
  138. {
  139. }
  140.  
  141. void ata_serial_print (const char *str)
  142. {
  143. }
  144.  
  145.  
  146. /* ++roman:
  147.  *
  148.  * This function does a reset on machines that lack the ability to
  149.  * assert the processor's _RESET signal somehow via hardware. It is
  150.  * based on the fact that you can find the initial SP and PC values
  151.  * after a reset at physical addresses 0 and 4. This works pretty well
  152.  * for Atari machines, since the lowest 8 bytes of physical memory are
  153.  * really ROM (mapped by hardware). For other 680x0 machines: don't
  154.  * know if it works...
  155.  *
  156.  * To get the values at addresses 0 and 4, the MMU better is turned
  157.  * off first. After that, we have to jump into physical address space
  158.  * (the PC before the pmove statement points to the virtual address of
  159.  * the code). Getting that physical address is not hard, but the code
  160.  * becomes a bit complex since I've tried to ensure that the jump
  161.  * statement after the pmove is in the cache already (otherwise the
  162.  * processor can't fetch it!). For that, the code first jumps to the
  163.  * jump statement with the (virtual) address of the pmove section in
  164.  * an address register . The jump statement is surely in the cache
  165.  * now. After that, that physical address of the reset code is loaded
  166.  * into the same address register, pmove is done and the same jump
  167.  * statements goes to the reset code. Since there are not many
  168.  * statements between the two jumps, I hope it stays in the cache.
  169.  *
  170.  * The C code makes heavy use of the GCC features that you can get the
  171.  * address of a C label. No hope to compile this with another compiler
  172.  * than GCC!
  173.  */
  174.   
  175. void __volatile__ atari_reset( void )
  176.  
  177. {    long    tc_val = 0, *tc_val_p = &tc_val;
  178.     void    *jmp_addr;
  179.     void    *after_jmp_addr = (void *)VTOP( &&after_jmp );
  180.     
  181.     cli();
  182.     jmp_addr = &&disable_mmu;
  183.     goto before_jmp;
  184.  
  185.   disable_mmu:
  186.     jmp_addr = after_jmp_addr;
  187.     __asm__ __volatile__
  188.         ( "pmove    %0@,tc"
  189.           : /* no outputs */
  190.           : "a" (tc_val_p)
  191.         );
  192.   before_jmp:
  193.     __asm__ __volatile__
  194.         ( "jmp        %1@"
  195.           : /* no outputs */
  196.           : "a" (tc_val_p), "a" (jmp_addr)
  197.         );
  198.   after_jmp:
  199.     __asm__ __volatile__
  200.         ( "movel    0x0,sp\n\t"
  201.           "movel    0x4,a0\n\t"
  202.           "jmp        a0@"
  203.           : /* no outputs */
  204.           : /* no inputs */
  205.           : "a0"
  206.         );
  207. }
  208.  
  209.